/**
 * 复杂条件搜索
 */
layui.define(['form', 'layer', 'laydate', 'multiSelect'], function (exports) {
    var $ = layui.$
        , laydate = layui.laydate
        , form = layui.form
        , multiSelect = layui.multiSelect

        //字符常量
        , MOD_NAME = 'complexSearch'
        // 页面html
        ,
        SEARCH_PAGE = '<form class="layui-form" method="post" onsubmit="return false;" style="padding: 10px 15px"> ' +
            '        <div class="search-content layui-row"></div> ' +
            '        <div class="layui-form-item"> ' +
            '            <button class="layui-btn layui-btn-sm zsa-search-add" type="button">添加条件</button> ' +
            '            <div class="layui-input-block" style="float: right;min-height: auto;"> ' +
            '                <button class="layui-btn layui-btn-sm search-submit" type="submit" lay-submit>搜索</button> ' +
            '                <button type="reset" class="layui-btn layui-btn-sm layui-btn-primary zsa-search-reset">重置</button> ' +
            '            </div> ' +
            '        </div> ' +
            '    </form>'
        // 条件行 html
        , SEARCH_ITEM = '<div class="layui-row zsa-filed-item layui-col-xs12 layui-col-sm6 layui-col-lg4"> ' +
        '        <div class="layui-col-xs3 zsa-search-field"> ' +
        '            <select name="fieldName" lay-verify="required" lay-search></select> ' +
        '        </div> ' +
        '        <div class="layui-col-xs2 zsa-search-formula"> ' +
        '            <select name="formula" lay-verify="required" lay-search> ' +
        '            </select> ' +
        '        </div> ' +
        '        <div class="layui-col-xs6 zsa-search-val"> ' +
        '            <input type="text" name="value" autocomplete="off" class="layui-input"> ' +
        '        </div> ' +
        '        <div class="layui-col-xs1"> ' +
        '            <i class="layui-icon zsa-delete zsa-search-delete">&#x1006;</i> ' +
        '        </div> ' +
        '    </div>'
        , formulas = [
            {formula: '=', title: '等于'},
            {formula: '>', title: '大于'},
            {formula: '<', title: '小于'},
            {formula: 'range', title: '范围'},
            {formula: '<>', title: '不等于'},
            {formula: '<->', title: '包含'},
            {formula: '->', title: '开始于'},
            {formula: '<-', title: '结束于'},
            {formula: 'in', title: 'IN'},
            {formula: 'notin', title: 'NOT IN'},
            {formula: 'null', title: '为空'},
            {formula: 'notnull', title: '不为空'},
        ]
        //外部接口
        , complexSearch = {
            index: layui.complexSearch ? (layui.complexSearch.index + 10000) : 0,
            //设置全局项
            set: function (options) {
                var that = this;
                that.config = $.extend({}, that.config, options);
                return that;
            }

            //事件监听
            , on: function (events, callback) {
                return layui.onevent.call(this, MOD_NAME, events, callback);
            }
        }

        //操作当前实例
        , thisIns = function () {
            var that = this
                , options = that.config
                , id = options.id || options.index;

            return {
                reload: function (options) {
                    that.reload.call(that, options);
                }
                , config: options
                , submit: function () {
                    that.submit();
                }
                , setDefaultValues: function (data) {
                    that.setDefaultValues(data);
                }
            }
        }

        //构造器
        , ComplexSearch = function (options) {
            var that = this;
            that.index = ++complexSearch.index;
            that.id = that.config.id;
            that.config = $.extend({}, that.config, complexSearch.config, options);
            that.init();
            that.render();
        };
    $('head').append('<style>.my-layui-layer .layui-layer-btn {padding-top: 0 !important;}</style>');
    //默认配置
    ComplexSearch.prototype.config = {
        // 弹窗宽度
        width: 500
        // 弹窗高度
        , height: 350
        // , returnFormat: {
        //     fieldName: 'val',
        //     formulaName: 'formula',
        //     valueName: 'value',
        //     dataTypeName: 'dataType'
        // }
        , simplify: true
        , data: []
        // , data: [{
        //     field: "field" // 字段名
        //     , title: "title" //名称
        //     , editType: "text" //编辑框类型 text、number、date、select
        //     , dataType: "string" //数据类型（判断符号） string、number、date
        //     , formulas: ["=", ">", "<", "<>", "<->", "<-", "->", "null", "notnull", "in", "notin", "range"]
        //     //选择符列表,只有一个时默认选中，为null或者个数为0时显示全部
        //     , formula: "=" //默认选择符
        //     , options: [{key: '请选择', value: ''}] //select options
        // }]
        // 是否是动态的 （false 顺序加载所有字段）
        , isDynamic: true
        // 指定容器
        // , container: "#container"
        // 指定触发弹窗的按钮
        // , btn: "#btn",
    };
    // 初始化一些数据
    ComplexSearch.prototype.init = function () {
        var that = this, options = that.config, selectOptions = '<option value="">--请选择--</option>';
        // 创建select的option
        $.each(that.config.data, function (i, e) {
            if (e === undefined) return true;
            selectOptions = selectOptions + '<option value="' + e.field + '">' + e.title + '</option>';
        });
        that.selectFieldOptionsHtml = selectOptions, selectOptions = '<option value="">--请选择--</option>';
        $.each(formulas, function (i, e) {
            if (e === undefined) return true;
            selectOptions = selectOptions + '<option value="' + e.formula + '">' + e.title + '</option>';
        });
        that.selectFormulaOptionsHtml = selectOptions;
    };
    // 添加行
    ComplexSearch.prototype.addItem = function (defaultData, configData) {
        var that = this, options = that.config, elem = options.elem, item = $(SEARCH_ITEM)
            , deleteBtn = item.find("i.zsa-search-delete"), fieldNameSelect = item.find('select[name=fieldName]')
            , formulaSelect = item.find('select[name=formula]');
        fieldNameSelect.attr('lay-filter', 'search-field-select-' + that.index)
            , formulaSelect.attr('lay-filter', 'search-formula-select-' + that.index)
            , fieldNameSelect.html(that.selectFieldOptionsHtml);
        options.isDynamic ? (deleteBtn.click(function (e) {
                that.deleteItem(item);
            }), options.container || item.attr('class', 'layui-row zsa-filed-item'), (!options.container && options.width >= 900) && item.addClass("layui-col-xs6"))
            : (deleteBtn.remove(), item.find('.zsa-search-formula').removeClass('layui-col-xs2').addClass('layui-col-xs3'));
        elem.find('div.search-content').append(item);
        form.render(null, "search-form-" + that.index);
        multiSelect.render("select", "search-form-" + that.index);
        if (defaultData) { // 设置默认值
            var dd;
            dd = fieldNameSelect.next().find("dl dd[lay-value='" + defaultData.field + "']"), dd.html() ? (dd.data("defaultData", defaultData), dd.click()) : fieldNameSelect.val(defaultData.field);
        }
        return item;
    };
    // 移除行
    ComplexSearch.prototype.deleteItem = function (elem) {
        elem && elem.remove();
    };
    //渲染视图
    ComplexSearch.prototype.render = function (options) {
        var that = this, options = (that.config = options || that.config), data = options.data
            , content = $(SEARCH_PAGE), id = that.index;
        content.attr("lay-filter", "search-form-" + id);
        options.isDynamic || (content.find('button.zsa-search-add,button.zsa-search-reset').remove(), content.removeAttr('style')), (options.submit || options.submit === false) && content.find('button.search-submit').hide(); //如果是静态的 移除添加条件按钮
        content.find('button.search-submit').attr('lay-filter', 'complex-search-' + id);
        if (options.container) $(options.container).html(content), options.elem = content, that.initClick(), options.isDynamic || that.loadAll();
        else if (options.btn) options.btn = $(options.btn), options.btn.click(function (e) {
            var cancel = function () { // 关闭回调
                that.cacheData = []; // 缓存历史
                options.elem.find('div.zsa-filed-item').each(function (i, e) {
                    var table_search_data = that.obtainVal(this);
                    table_search_data && that.cacheData.push(table_search_data);
                });
            };
            layer.open({
                type: 1,
                id: MOD_NAME + that.id,
                move: false,
                area: [options.width + 'px', options.height + 'px'],
                fix: false,
                maxmin: true,
                shadeClose: true,
                shade: 0.4,
                title: '条件搜索',
                btn: ['关闭'],
                content: content.prop("outerHTML"),
                success: function (layero, index) {
                    $('#layui-layer' + index).addClass('my-layui-layer');
                    var content = $('#layui-layer' + index + ' .layui-layer-content');
                    content.height(content.height() + 17);

                    layero.find('div.search-content').empty(); // 清理内容区域
                    options.elem = layero.find('form'), that.initClick(), options.isDynamic || that.loadAll();
                    // 还原历史缓存
                    that.cacheData && $.each(that.cacheData, function (i, e) {
                        that.addItem(e);
                    });
                },
                yes: function (index, layero) {
                    layero.find('.layui-layer-close1').click();
                }, btn2: cancel, cancel: cancel
            });
        });
        else console.log("没有找到触发按钮（btn）或者容器(container)")
    };
    // 初始化所有字段   isDynamic==false
    ComplexSearch.prototype.loadAll = function () {
        var that = this, options = that.config;
        $.each(options.data, function (i, e) {
            that.addItem(e, e);
        })
    };
    ComplexSearch.prototype.initClick = function () {
        var that = this, options = that.config, id = that.index, elem = options.elem;
        // 字段选择事件
        form.on('select(search-field-select-' + id + ')', function (data) {
            var field = data.value;
            var formulaElem = $(data.elem).closest('div.zsa-filed-item').find('.zsa-search-formula').find('select');
            var fieldData = $.extend(that.getFieldData(field), $(this).data('defaultData') || {});
            $(this).removeData('defaultData'), formulaElem.html(that.selectFormulaOptionsHtml);
            formulaElem.find('option').each(function (i1, e1) {
                var have = false;
                if (fieldData.formulas && Array.isArray(fieldData.formulas) && fieldData.formulas.length > 0)
                    $.each(fieldData.formulas, function (i, e) {
                        if ($(e1).attr('value') === e)
                            return have = true, false;
                    });
                else have = true;
                if ($(e1).attr('value') === 'in' || $(e1).attr('value') === 'notin') {
                    if (fieldData['editType'] !== 'select' || !Array.isArray(fieldData['options'])) have = false;
                }
                if (options.simplify)
                    if (!have) return $(e1).remove(), true;
                if (!have) $(e1).attr('disabled', 'disabled');
                else $(e1).removeAttr('disabled');
            });
            form.render('select', "search-form-" + id);
            var dd;
            dd = formulaElem.next().find("dl dd[lay-value='" + fieldData.formula + "']")
                , dd = dd.html() ? dd.data("defaultData", fieldData) : (fieldData.formulas && fieldData.formulas.length > 0 ? formulaElem.next().find("dl dd[lay-value='" + fieldData.formulas[0] + "']").eq(0)
                : formulaElem.next().find("dl dd").eq(0));
            dd.click();
        });
        // 条件选择事件
        form.on('select(search-formula-select-' + id + ')', function (data) {
            var itemElem = $(data.elem).closest('div.zsa-filed-item'), valPren = itemElem.find('.zsa-search-val');
            var fieldElem = itemElem.find('.zsa-search-field select'), field = fieldElem.val(), formula = data.value;
            var fieldConfig = $.extend(that.getFieldData(field), $(this).data('defaultData') || {}),
                editType = fieldConfig['editType'], valElem;
            $(this).removeData('defaultData');
            switch (formula) {
                case 'null':
                case 'notnull':
                    valElem = $('<input name="value" placeholder="不需要填" type="text" autocomplete="off" class="layui-input layui-disabled" disabled/>')
                    break;
                case 'range':
                    var front, after;
                    if (editType === 'select' && Array.isArray(fieldConfig.options)) {
                        front = createSelect();
                        after = createSelect();
                    } else {
                        front = $('<input name="value" autocomplete="off" class="layui-input">');
                        after = $('<input name="value" autocomplete="off" class="layui-input">');
                        setAttribute(front);
                        setAttribute(after);
                    }
                    valElem = $('<div class="zsa-val-range-container layui-hide"></div>').append(front).append('<span class="zsa-val-range-symbol">~~</span>').append(after);
                    if (fieldConfig.value) {
                        var split = fieldConfig.value.split('~~');
                        front.val(split[0]), after.val(split[1]);
                    }
                    after.addClass('zsa-val-range-right');
                    break;
                case 'in':
                case 'notin':
                    if (editType === 'select' && Array.isArray(fieldConfig.options)) {
                        valElem = createSelect(true);
                        fieldConfig.value && ($.each(fieldConfig.value, function (i, e) {
                            if (e === undefined) return true;
                            $(valElem).find('option[value=' + e + ']').attr("selected", "selected");
                        }))
                    }
                    break;
                default:
                    if (editType === 'select' && Array.isArray(fieldConfig.options)) {
                        valElem = createSelect();
                    } else {
                        valElem = $('<input name="value" autocomplete="off" class="layui-input">');
                        setAttribute(valElem);
                    }
                    fieldConfig.value && valElem.val(fieldConfig.value);
            }
            valPren.html(valElem);
            options.isDynamic || fieldElem.attr('disabled', true);
            form.render(null, "search-form-" + id);
            multiSelect.render("select", "search-form-" + id);
            if (formula === 'range') valPren.find('.zsa-val-range-container').removeClass('layui-hide');

            function createSelect(multiple) {
                var selectElem = $('<select name="value" lay-search></select>'), haveNull = false, option_htmls = '';
                multiple && selectElem.attr('multiple', multiple);
                $.each(fieldConfig.options, function (i, e) {
                    if (e === undefined) return true;
                    if (e.value === '' || e.VALUE === '') haveNull = true;
                    option_htmls += '<option value="' + (e.value || e.VALUE || '') + '">' + (e.key || e.KEY) + '</option>';
                });
                haveNull || selectElem.append('<option value="">---请选择---</option>');
                selectElem.append(option_htmls);
                return selectElem;
            }

            function setAttribute(elem) {
                switch (editType) {
                    case 'date':
                        laydate.render({
                            elem: elem[0]
                            , type: fieldConfig['dateType'] || 'date'
                        });
                        elem.attr('type', 'text');
                        switch (fieldConfig['dateType']) {
                            case 'year':
                                elem.attr('placeholder', 'yyyy');
                                break;
                            case 'month':
                                elem.attr('placeholder', 'yyyy-mm');
                                break;
                            case 'time':
                                elem.attr('placeholder', 'hh:mi:ss');
                                break;
                            case 'datetime':
                                elem.attr('placeholder', 'yyyy-mm-dd hh:mi:ss');
                                break;
                            case 'date':
                            default :
                                elem.attr('placeholder', 'yyyy-mm-dd');
                        }
                        break;
                    case 'text':
                        elem.attr('type', editType).attr('placeholder', '任意字符串');
                        break;
                    case 'number':
                        elem.attr('type', editType).attr('placeholder', '数字');
                        break;
                    default:
                        elem.attr('type', 'text');
                }
            }
        });
        // 提交事件
        form.on('submit(complex-search-' + id + ')', function (data) {
            that.searchData = [], returnData = [];
            elem.find('div.zsa-filed-item').each(function (i, e) {
                var result = that.obtainVal(this, true);
                if (result) {
                    if (result.formula.indexOf('null') < 0 && (result.value === undefined || result.value === "undefined" || result.value == null || result.value === '')) return true;
                    var fieldData = $.extend(that.getFieldData(result.field), result);
                    fieldData['options'] && delete fieldData['options']
                        , fieldData['title'] && delete fieldData['title']
                        , fieldData['formulas'] && delete fieldData['formulas']
                        , fieldData['editType'] && delete fieldData['editType'];
                    var returnFormat = that.config.returnFormat;
                    if (returnFormat) {
                        var temp = {};
                        $.each(fieldData, function (k, v) {
                            if (v === undefined) return true;
                            if (k === 'field' && returnFormat['fieldName']) return temp[returnFormat['fieldName']] = v, true;
                            if (k === 'formula' && returnFormat['formulaName']) return temp[returnFormat['formulaName']] = v, true;
                            if (k === 'value' && returnFormat['valueName']) return temp[returnFormat['valueName']] = v, true;
                            if (k === 'dataType' && returnFormat['dataTypeName']) return temp[returnFormat['dataTypeName']] = v, true;
                            temp[k] = v;
                        }), returnData.push(temp);
                    } else returnData.push(fieldData);
                    that.searchData.push(fieldData);
                }
            });
            options.search && options.search(returnData, returnData.length);
            return false; //阻止表单跳转。如果需要表单跳转，去掉这段即可。
        });
        // 绑定 添加行事件
        elem.find("button.zsa-search-add").click(function (e) {
            that.addItem();
        });
        (options.submit && options.submit !== false) && $(options.submit).click(function (e) {
            elem.find('button.search-submit').click();
        })
    };

    ComplexSearch.prototype.submit = function () {
        var that = this, elem = that.config.elem;
        elem.find('button.search-submit').click();
    };

    ComplexSearch.prototype.setDefaultValues = function (data) {
        var that = this, elem = that.config.elem;
        if (!(data instanceof Array)) return;
        $.each(data, function (i, e) {
            elem.find('select[name=fieldName]').each(function (i1, e1) {
                if (e['field'] === $(this).val()) {
                    var itemElem = $(this).closest('.zsa-filed-item'),
                        formulaDd = itemElem.find('.zsa-search-formula .layui-form-select dl dd[lay-value="' + e['formula'] + '"]');
                    if (formulaDd.length === 0 || !e['value']) return false;
                    formulaDd.click();
                    var valueElem = itemElem.find('.zsa-search-val [name="value"]');
                    var formula = e['formula'], fieldData = that.getFieldData(e['field']);
                    if (formula === undefined || formula === '' || (fieldData.formulas && fieldData.formulas.indexOf(formula) < 0))
                        formula = fieldData.formulas[0];
                    switch (formula) {
                        case 'range':
                            var split = e['value'].split('~~');
                            valueElem.eq(0).val(split[0]);
                            valueElem.eq(1).val(split[1]);
                            break;
                        case 'in':
                        case 'notin':
                            $.each(e['value'], function (i, e) {
                                if (e === undefined) return true;
                                valueElem.find('option[value=' + e + ']').attr("selected", "selected");
                            });
                            break;
                        default:
                            valueElem.val(e['value']);
                    }
                }
            });
        });
        form.render(null, "search-form-" + that.index);
        multiSelect.render("select", "search-form-" + that.index);
    };

    ComplexSearch.prototype.obtainVal = function (itemElem, tag) {
        var field = $(itemElem).find('select[name=fieldName]')[0].value;
        if (field !== undefined && field != null && field !== '') {
            var formula = $(itemElem).find('select[name=formula]').val(), value;
            var valElem = $(itemElem).find('input[name=value],select[name=value]');
            switch (formula) {
                case 'range':
                    value = valElem[0].value + '~~' + valElem[1].value;
                    var split = value.split("~~");
                    if (tag && (split[0].trim() === '' || split[1].trim() === '')) return;
                    break;
                case 'in':
                case 'notin':
                    value = [];
                    valElem.find('option:selected').each(function () {
                        var val = $(this).val();
                        if (val !== undefined && val != null && val !== 'undefined' && val !== '') value.push(val);
                    });
                    if (tag && value.length === 0) return;
                    break;
                default:
                    value = valElem[0].value;
            }
            return {
                field: field,
                formula: formula,
                value: value
            }
        }
    };

    ComplexSearch.prototype.getFieldData = function (field) {
        var data = this.config.data, fieldData = {};
        $.each(data, function (i, e) {
            if (e['field'] === field) return $.extend(fieldData, e), false;
        });
        return fieldData;
    };

    // 重新加载
    ComplexSearch.prototype.reload = function (options) {
        var that = this, this_options = that.config;
        that.render($.extend(true, {}, this_options, options));
    };

    //核心入口
    complexSearch.render = function (options) {
        var ins = new ComplexSearch(options);
        return thisIns.call(ins);
    };

    layui.link(layui.cache.base + 'complexSearch/complexSearch.css?v=' + (layui.cache.version ? layui.cache.version : '1'));
    exports(MOD_NAME, complexSearch);
});




